/**
 * 
 */
package com.carnation.qa.socketserver.proxy.moi;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.carnation.mong.platform.domain.MOIAttribute;
import com.carnation.mong.platform.domain.MOIBase;
import com.carnation.mong.platform.domain.MOIDRelation;
import com.carnation.mong.platform.domain.MOIData;
import com.carnation.mong.platform.domain.MOIDataRevision;
import com.carnation.mong.platform.domain.MOIDomain;
import com.carnation.mong.platform.domain.MOIMRelation;
import com.carnation.mong.platform.domain.MOIModel;
import com.carnation.mong.platform.domain.MOIPackage;
import com.carnation.mong.platform.domain.MOIRelationType;
import com.carnation.mong.platform.service.DataService;
import com.carnation.mong.platform.um.Group;
import com.carnation.mong.platform.um.Privilege;
import com.carnation.mong.platform.um.Role;
import com.carnation.mong.platform.um.User;
import com.carnation.qa.socketserver.domain.Item;
import com.carnation.qa.socketserver.proxy.AbstractServiceImpl;

/**
 * @author Nick
 * 
 */
public abstract class AbstractMOIServiceImpl extends AbstractServiceImpl {

	private final Log log = LogFactory.getLog(getClass());

	public AbstractMOIServiceImpl(List<Item> items) {
		super(items);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.carnation.qa.socketserver.proxy.AbstractServiceImpl#run()
	 */
	@Override
	public String run() {
		String returnStr = super.run();
		ServiceFactory.commit();
		return returnStr;
	}

	protected Map<String, Object> instanceStringObjectMap(Item item) {
		Map<String, Object> map = new HashMap<String, Object>();
		String[] parts;
		for (Item i : item.getChildren()) {
			parts = i.getLabelParts();
			map.put(parts[0], getObject(parts[1]));
		}
		return map;
	}

	protected List<MOIAttribute> instanceMOIAttributeList(Item item) {
		List<MOIAttribute> list = new ArrayList<MOIAttribute>();
		for (Item i : item.getChildren()) {
			// 序号
			list.add(instanceMOIAttribute(i.getChildren().get(0)));
		}
		return list;
	}

	protected MOIDomain instanceMOIDomain(Item item) {
		MOIDomain domain = new MOIDomain();
		for (Item i : item.getChildren()) {
			setMOIDomain(domain, i);
		}
		return domain;
	}

	protected MOIPackage instanceMOIPackage(Item item) {
		MOIPackage p = new MOIPackage();
		for (Item i : item.getChildren()) {
			setMOIPackage(p, i);
		}
		return p;
	}

	private void setMOIPackage(MOIPackage p, Item i) {
		String[] parts = i.getLabelParts();
		String value = getString(parts[1]);
		setIds(parts, p);
		if (parts[0].equals("setParentPackageId")) {
			p.setParentPackageId((value));
		}
	}

	protected MOIModel instanceMOIModel(Item item) {
		MOIModel model = new MOIModel();
		for (Item i : item.getChildren()) {
			setMOIModel(model, i);
		}
		return model;
	}

	protected MOIMRelation instanceMOIMRelation(Item item) {
		MOIMRelation model = new MOIMRelation();
		for (Item i : item.getChildren()) {
			setMOIMRelation(model, i);
		}
		return model;
	}

	@SuppressWarnings("unchecked")
	protected List instanceList(Item item) {
		List list = new ArrayList();
		for (Item i : item.getChildren()) {
			// 序号
			list.add(instanceObject(i.getChildren().get(0)));
		}
		return list;
	}

	private Object instanceObject(Item item) {
		String label = item.getLabel();
		if (item.getChildren().isEmpty()) {
			return super.getObject(label);
		} else {
			if (label.equals(User.class.getName())
					|| label.equals(User.class.getSimpleName())) {
				return instanceUser(item);
			} else if (label.equals(Role.class.getName())
					|| label.equals(Role.class.getSimpleName())) {
				return instanceRole(item);
			} else if (label.equals(Group.class.getName())
					|| label.equals(Group.class.getSimpleName())) {
				return instanceUser(item);
			} else if (label.equals(Privilege.class.getName())
					|| label.equals(Privilege.class.getSimpleName())) {
				return instancePrivilege(item);
			} else if (label.equals(MOIAttribute.class.getName())
					|| label.equals(MOIAttribute.class.getSimpleName())) {
				return instanceMOIAttribute(item);
			} else if (label.equals(MOIData.class.getName())
					|| label.equals(MOIData.class.getSimpleName())) {
				return instanceMOIData(item);
			} else if (label.equals(MOIDataRevision.class.getName())
					|| label.equals(MOIDataRevision.class.getSimpleName())) {
				return instanceMOIDataRevision(item);
			} else if (label.equals(MOIDomain.class.getName())
					|| label.equals(MOIDomain.class.getSimpleName())) {
				return instanceMOIDomain(item);
			} else if (label.equals(MOIDRelation.class.getName())
					|| label.equals(MOIDRelation.class.getSimpleName())) {
				return instanceMOIDRelation(item);
			} else if (label.equals(MOIModel.class.getName())
					|| label.equals(MOIModel.class.getSimpleName())) {
				return instanceMOIModel(item);
			} else if (label.equals(MOIMRelation.class.getName())
					|| label.equals(MOIMRelation.class.getSimpleName())) {
				return instanceMOIMRelation(item);
			} else if (label.equals(MOIPackage.class.getName())
					|| label.equals(MOIPackage.class.getSimpleName())) {
				return instanceMOIPackage(item);
			} else if (label.equals(MOIRelationType.class.getName())
					|| label.equals(MOIRelationType.class.getSimpleName())) {
				return instanceMOIRelationType(item);
			} else {
				throw new IllegalArgumentException(label);
			}
		}
	}

	protected Group instanceGroup(Item item) {
		Long id = 0L, parentId = 0L;
		String name = null, desc = null, rdn = null;
		for (Item i : item.getChildren()) {
			String[] parts = i.getLabelParts();
			if (parts[0].equals("setId")) {
				id = (getLong(parts[1]));
			} else if (parts[0].equals("setDescription")) {
				desc = (getString(parts[1]));
			} else if (parts[0].equals("setName")) {
				name = (getString(parts[1]));
			} else if (parts[0].equals("setRDN")) {
				rdn = (getString(parts[1]));
			} else if (parts[0].equals("setAttribute")) {
				if (log.isWarnEnabled()) {
					log.warn("unsuported operation:" + parts[0]);
				}
			}
		}
		Group group = new Group(id, rdn, name, desc, parentId);
		return group;
	}

	protected Role instanceRole(Item item) {
		Long id = 0L;
		String name = null, desc = null, rdn = null;
		for (Item i : item.getChildren()) {
			String[] parts = i.getLabelParts();
			if (parts[0].equals("setId")) {
				id = (getLong(parts[1]));
			} else if (parts[0].equals("setDescription")) {
				desc = (getString(parts[1]));
			} else if (parts[0].equals("setName")) {
				name = (getString(parts[1]));
			} else if (parts[0].equals("setRDN")) {
				rdn = (getString(parts[1]));
			} else if (parts[0].equals("setAttribute")) {
				if (log.isWarnEnabled()) {
					log.warn("unsuported operation:" + parts[0]);
				}
			}
		}
		Role role = new Role(id, rdn, name, desc);
		return role;
	}

	protected Privilege instancePrivilege(Item item) {
		Long id = 0L;
		String name = null, desc = null, rdn = null;
		boolean isSystem = false;
		for (Item i : item.getChildren()) {
			String[] parts = i.getLabelParts();
			if (parts[0].equals("setId")) {
				id = (getLong(parts[1]));
			} else if (parts[0].equals("setDescription")) {
				desc = (getString(parts[1]));
			} else if (parts[0].equals("setName")) {
				name = (getString(parts[1]));
			} else if (parts[0].equals("setRDN")) {
				rdn = (getString(parts[1]));
			} else if (parts[0].equals("setIsSystem")) {
				isSystem = getBoolean(parts[1]);
			}
		}
		Privilege instance = new Privilege(id, rdn, name, desc, isSystem);
		return instance;
	}

	protected User instanceUser(Item item) {
		Long id = 0L;
		String name = null, password = null, userName = null, email = null, desc = null, rdn = null;
		for (Item i : item.getChildren()) {
			String[] parts = i.getLabelParts();
			if (parts[0].equals("setId")) {
				id = (getLong(parts[1]));
			} else if (parts[0].equals("setDescription")) {
				desc = (getString(parts[1]));
			} else if (parts[0].equals("setName")) {
				name = (getString(parts[1]));
			} else if (parts[0].equals("setRDN")) {
				rdn = (getString(parts[1]));
			} else if (parts[0].equals("setPassword")) {
				password = getString(parts[1]);
			} else if (parts[0].equals("setUserName")) {
				userName = getString(parts[1]);
			} else if (parts[0].equals("setEmail")) {
				email = getString(parts[1]);
			}
		}
		User user = new User(id, rdn, name, password, userName, email, desc);
		return user;
	}

	/**
	 * 设置模型对象
	 * 
	 * @param model
	 * @param i
	 */
	private void setMOIMRelation(MOIMRelation model, Item i) {
		String[] parts = i.getLabelParts();
		setIds(parts, model);
		if (parts[0].equals("setLimitation")) {
			model.setLimitation(getString(parts[1]));
		} else if (parts[0].equals("setRelationTypeId")) {
			model.setRelationTypeId(getString(parts[1]));
		} else if (parts[0].equals("setSourceModelId")) {
			model.setSourceModelId(getString(parts[1]));
		} else if (parts[0].equals("setTargetModelId")) {
			model.setTargetModelId(getString(parts[1]));
		}
	}

	/**
	 * 设置模型对象
	 * 
	 * @param model
	 * @param i
	 */
	private void setMOIModel(MOIModel model, Item i) {
		String[] parts = i.getLabelParts();
		setIds(parts, model);
		if (parts[0].equals("setAbstract")) {
			model.setAbstract(getBoolean(parts[1]));
		} else if (parts[0].equals("setPackageId")) {
			model.setPackageId(getString(parts[1]));
		}
	}

	protected MOIData instanceMOIData(Item item) {
		MOIData data = new MOIData();
		for (Item i : item.getChildren()) {
			setMOIData(data, i);
		}
		return data;
	}

	protected MOIAttribute instanceMOIAttribute(Item item) {
		MOIAttribute a = new MOIAttribute();
		for (Item i : item.getChildren()) {
			setMOIAttribute(a, i);
		}
		return a;
	}

	private void setMOIAttribute(MOIAttribute a, Item i) {
		String[] parts = i.getLabelParts();
		setIds(parts, a);
		if (parts[0].equals("setDataType")) {
			a.setDataType(getDataType(getString(parts[1])));
		} else if (parts[0].equals("setDefaultValue")) {
			a.setDefaultValue(getString(parts[1]));
		} else if (parts[0].equals("setMax")) {
			a.setMax(getInteger(parts[1]));
		} else if (parts[0].equals("setMin")) {
			a.setMin(getInteger(parts[1]));
		} else if (parts[0].equals("setModelId")) {
			a.setModelId(getString(parts[1]));
		} else if (parts[0].equals("setNotNull")) {
			a.setNotNull(getBoolean(parts[1]));
		}
	}

	/**
	 * 获取属性数据类型字符串
	 * 
	 * @param identify
	 * @return
	 */
	private String getDataType(String identify) {
		if (identify.equals("DT_BOOLEAN")) {
			return MOIAttribute.DT_BOOLEAN;
		} else if (identify.equals("DT_DATE")) {
			return MOIAttribute.DT_DATE;
		} else if (identify.equals("DT_DOUBLE")) {
			return MOIAttribute.DT_DOUBLE;
		} else if (identify.equals("DT_FLOAT")) {
			return MOIAttribute.DT_FLOAT;
		} else if (identify.equals("DT_INTEGER")) {
			return MOIAttribute.DT_INTEGER;
		} else if (identify.equals("DT_IPADDRESS")) {
			return MOIAttribute.DT_IPADDRESS;
		} else if (identify.equals("DT_LONG")) {
			return MOIAttribute.DT_LONG;
		} else if (identify.equals("DT_PASSWORD")) {
			return MOIAttribute.DT_PASSWORD;
		} else if (identify.equals("DT_STRING")) {
			return MOIAttribute.DT_STRING;
		} else if (identify.equals("DT_TEXT")) {
			return MOIAttribute.DT_TEXT;
		} else {
			throw new IllegalArgumentException(identify);
		}
	}

	protected MOIDRelation instanceMOIDRelation(Item item) {
		MOIDRelation data = new MOIDRelation();
		for (Item i : item.getChildren()) {
			setMOIDRelation(data, i);
		}
		return data;
	}

	private void setMOIDRelation(MOIDRelation data, Item i) {
		String[] parts = i.getLabelParts();
		setIds(parts, data);
		if (parts[0].equals("setRelationTypeId")) {
			data.setRelationTypeId(getString(parts[1]));
		} else if (parts[0].equals("setSourceDataId")) {
			data.setSourceDataId(getString(parts[1]));
		} else if (parts[0].equals("setTargetDataId")) {
			data.setTargetDataId(getString(parts[1]));
		}
	}

	protected MOIRelationType instanceMOIRelationType(Item item) {
		MOIRelationType type = new MOIRelationType();
		for (Item i : item.getChildren()) {
			setMOIRelationType(type, i);
		}
		return type;
	}

	protected MOIDataRevision instanceMOIDataRevision(Item item) {
		MOIDataRevision r = new MOIDataRevision();
		for (Item i : item.getChildren()) {
			setMOIDataRevision(r, i);
		}
		return r;
	}

	private void setMOIDomain(MOIDomain domain, Item i) {
		setIds(i.getLabelParts(), domain);
	}

	/**
	 * 设置关系类型
	 * 
	 * @param type
	 * @param i
	 */
	private void setMOIRelationType(MOIRelationType type, Item i) {
		String[] parts = i.getLabelParts();
		setIds(parts, type);
		if (parts[0].equals("setAbstract")) {
			type.setAbstract(getBoolean(parts[1]));
		} else if (parts[0].equals("setBuildIn")) {
			type.setBuildIn(getBoolean(parts[1]));
		} else if (parts[0].equals("setParentRTId")) {
			type.setParentRTId(getString(parts[1]));
		}
	}

	/**
	 * 设置数据对象
	 * 
	 * @param data
	 * @param i
	 */
	private void setMOIData(MOIData data, Item i) {
		String[] parts = i.getLabelParts();
		if (parts[0].equals("setPath")) {
			String path = getString(parts[1]);
			try {
				data.setId(ServiceFactory.getService(DataService.class)
						.getDataByPath(path).getId());
			} catch (Exception e) {
				if (log.isWarnEnabled()) {
					log.warn(e.getMessage(), e);
				}
			}
		}
		setIds(parts, data);
		setAttribute(parts, data, i);
		setAttributeType(parts, data);
		setAttributeNameTypeMap(parts, data, i);
		if (parts[0].equals("setModelId")) {
			data.setModelId(getString(parts[1]));
		} else if (parts[0].equals("setParentId")) {
			data.setParentId(getString(parts[1]));
		}
	}

	/**
	 * 设置关系类型
	 * 
	 * @param type
	 * @param i
	 */
	private void setMOIDataRevision(MOIDataRevision r, Item i) {
		String[] parts = i.getLabelParts();
		if (parts[0].equals("setActorId")) {
			r.setActorId(getString(parts[1]));
		} else if (parts[0].equals("setActTime")) {
			r.setActTime(getDate((parts[1])));
		} else if (parts[0].equals("setActType")) {
			r.setActType(getString(parts[1]));
		} else if (parts[0].equals("setData")) {
			r.setData(instanceMOIData(i));
		} else if (parts[0].equals("setDataId")) {
			r.setDataId(getString(parts[1]));
		} else if (parts[0].equals("setId")) {
			r.setId(getString(parts[1]));
		} else if (parts[0].equals("setRevisionName")) {
			r.setRevisionName(getString(parts[1]));
		}

	}

	private void setIds(String[] parts, MOIBase data) {
		if (parts[0].equals("setId")) {
			data.setId(getString(parts[1]));
		} else if (parts[0].equals("setName")) {
			data.setName(getString(parts[1]));
		} else if (parts[0].equals("setDisplayName")) {
			data.setDisplayName(getString(parts[1]));
		} else if (parts[0].equals("setDescription")) {
			data.setDescription(getString(parts[1]));
		}
	}

	private void setAttribute(String[] parts, MOIData data, Item item) {
		if (parts[0].equals("setAttribute")) {
			// TODO not yet implemented
			if (log.isWarnEnabled()) {
				log.warn("not support 'setAttribute' method in MOIData");
			}
		}
	}

	private void setAttributeType(String[] parts, MOIData data) {
		if (parts[0].equals("setAttributeType")) {
			data.setAttributeType(parts[1], getString(parts[2]));
		}
	}

	private void setAttributeNameTypeMap(String[] parts, MOIData data, Item item) {
		if (parts[0].equals("setAttributeNameTypeMap")) {
			Map<String, String> map = new HashMap<String, String>();
			for (Item i : item.getChildren()) {
				String[] maps = i.getLabelParts();
				map.put(maps[0], getString(maps[1]));
			}
			data.setAttributeNameTypeMap(map);
		}
	}

}
